﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MLOCore
{
    public class Node
    {
        const char parseCharacters = ' ';

        public readonly string Value;
        public readonly NodeCollection Nodes;

        private static Dictionary<string, Node> _nodes = new Dictionary<string, Node>();

        public Single Compare(Node n)
        {
            if (n == null) return 0;

            int max = Math.Max(n.Nodes.Count, Nodes.Count);

            return ((Match(this, n).Count) / max);
        }

        public static List<Node> Match(Node n1, Node n2)
        {
            if (n1 == null || n2 == null) return null;

            List<Node> result = new List<Node>();

            if (n1 == n2)
                result.Add(n1);
            else if ((n1.Nodes.Count == 0 || n2.Nodes.Count == 0) && n1.Value != n2.Value)
                return null;
            else
            {
                result.AddRange(n1.Nodes.Where<Node>(n => n2.Nodes.Contains(n)));
            }

            return result;
        }

        #region Static Get Node
        /// <summary>
        /// Gets the node.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        public static Node GetNode(string value)
        {
            if (string.IsNullOrEmpty(value))
                throw new ArgumentNullException("value");

            if (_nodes.ContainsKey(value))
                return _nodes[value];
            else
            {
                Node n = new Node(value);
                _nodes.Add(n.Value, n);
                return n;
            }
        }
        #endregion

        #region Constructors
        private Node(string value)
        {
            string[] s = value.Split(parseCharacters);
            if (s.Length > 0)
            {
                this.Nodes = new NodeCollection();
                foreach (string item in s)
                {
                    this.Nodes.Add(Node.GetNode(item));
                }
                this.Value = value;
            }
            else
                this.Value = value;
        }

        private Node(NodeCollection nodes)
        {
            this.Nodes = nodes;
            this.Value = nodes.ToString();
        }
        #endregion

    }
}
